"""
====================================================================
配置文件 / Configuration File
====================================================================
说明：
1. 所有敏感配置项（密码、API密钥等）必须通过环境变量设置
2. 生产环境部署前请检查 .env 文件是否正确配置
3. 配置项说明详见 .env.example 文件
4. 如果缺少必需的环境变量，系统将在启动时抛出异常

Configuration file containing all configurable parameters.
All sensitive configurations (passwords, API keys) must be set via environment variables.
====================================================================
"""

import tempfile
import os
from typing import List, Optional
import sys
from pathlib import Path
from dotenv import load_dotenv

# ====================================================================
# 加载 .env 文件
# ====================================================================
# 获取项目根目录（config.py 所在目录）
BASE_DIR = Path(__file__).resolve().parent

# 加载 .env 文件（如果存在）
env_path = BASE_DIR / '.env'
if env_path.exists():
    load_dotenv(dotenv_path=env_path)
    print(f"✅ 已加载环境变量文件: {env_path}")
else:
    print(f"⚠️  未找到 .env 文件: {env_path}")
    print("   将使用系统环境变量和默认值")


def get_required_env(key: str, description: str = "") -> str:
    """
    获取必需的环境变量，如果不存在则抛出异常

    参数:
        key: 环境变量名称
        description: 环境变量描述（用于错误提示）

    返回:
        环境变量值

    抛出:
        ValueError: 当环境变量不存在时
    """
    value = os.getenv(key)
    if value is None:
        error_msg = f"❌ 缺少必需的环境变量: {key}"
        if description:
            error_msg += f" ({description})"
        error_msg += f"\n请在 .env 文件中配置此变量，参考 .env.example"
        raise ValueError(error_msg)
    return value


def get_env_with_warning(key: str, default: str, description: str = "") -> str:
    """
    获取环境变量，如果使用默认值则发出警告

    参数:
        key: 环境变量名称
        default: 默认值
        description: 环境变量描述

    返回:
        环境变量值或默认值
    """
    value = os.getenv(key)
    if value is None:
        print(f"⚠️  警告: 环境变量 {key} 未设置，使用默认值: {default}", file=sys.stderr)
        if description:
            print(f"   说明: {description}", file=sys.stderr)
    return value or default


# ====================================================================
# Elasticsearch 配置
# ====================================================================
# Elasticsearch 服务器地址列表（逗号分隔多个地址）
ELASTICSEARCH_HOSTS = os.getenv('ELASTICSEARCH_HOSTS', 'http://119.23.229.39:39200').split(',')

# Elasticsearch 请求超时时间（秒）
ELASTICSEARCH_REQUEST_TIMEOUT = int(os.getenv('ELASTICSEARCH_TIMEOUT', '10'))

# Elasticsearch 认证用户名（生产环境请通过环境变量设置）
ELASTICSEARCH_USERNAME = get_env_with_warning(
    'ELASTICSEARCH_USERNAME',
    'elastic',
    'Elasticsearch 用户名'
)

# Elasticsearch 认证密码（⚠️ 生产环境必须通过环境变量设置）
ELASTICSEARCH_PASSWORD = get_env_with_warning(
    'ELASTICSEARCH_PASSWORD',
    'zl800800',
    '⚠️  生产环境必须修改此密码'
)

# ====================================================================
# Redis 配置
# ====================================================================
# Redis 服务器地址
REDIS_HOST = os.getenv('REDIS_HOST', '120.79.123.134')

# Redis 服务器端口
REDIS_PORT = int(os.getenv('REDIS_PORT', '26000'))

# Redis 认证密码（⚠️ 生产环境必须通过环境变量设置）
REDIS_PASSWORD = get_env_with_warning(
    'REDIS_PASSWORD',
    'jingzhongyue1',
    '⚠️  生产环境必须修改此密码'
)

# Redis 最大连接数
REDIS_MAX_CONNECTIONS = int(os.getenv('REDIS_MAX_CONNECTIONS', '100'))

# Redis Socket 超时时间（秒）
REDIS_SOCKET_TIMEOUT = int(os.getenv('REDIS_SOCKET_TIMEOUT', '10'))

# ====================================================================
# MongoDB 配置（在 mongo_util.py 中使用）
# ====================================================================
# MongoDB 连接URI（⚠️ 生产环境必须通过环境变量设置）
MONGODB_URI = os.getenv(
    'MONGODB_URI',
    'mongodb://120.78.167.249:28464/JBN_PRO?authSource=admin&replicaSet=ZLKJ&tz_aware=true'
)

# MongoDB 数据库名称
MONGODB_DATABASE = os.getenv('MONGODB_DATABASE', 'JBN_PRO')

# MongoDB 连接池大小
MONGODB_MAX_POOL_SIZE = int(os.getenv('MONGODB_MAX_POOL_SIZE', '50'))

# MongoDB 服务器选择超时时间（毫秒）
MONGODB_SERVER_SELECTION_TIMEOUT_MS = int(os.getenv('MONGODB_SERVER_SELECTION_TIMEOUT_MS', '10000'))

# ====================================================================
# AI/LLM API 配置
# ====================================================================
# LaoZhang API 配置
LAOZHANG_API_BASE_URL = os.getenv('LAOZHANG_API_BASE_URL', 'https://api.laozhang.ai/v1')
LAOZHANG_API_KEY = os.getenv('LAOZHANG_API_KEY')  # 必须通过环境变量设置

# DeepSeek API 配置
DEEPSEEK_API_BASE_URL = os.getenv('DEEPSEEK_API_BASE_URL', 'https://api.deepseek.com')
DEEPSEEK_API_KEY = os.getenv('DEEPSEEK_API_KEY')  # 必须通过环境变量设置

# OpenAI API 配置
OPENAI_API_BASE_URL = os.getenv('OPENAI_API_BASE_URL', 'https://api.openai.com/v1')
OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')  # 必须通过环境变量设置

# 默认使用的 AI 模型
DEFAULT_AI_MODEL = os.getenv('DEFAULT_AI_MODEL', 'gpt-4o')

# AI API 调用速率限制（次/分钟）
AI_RATE_LIMIT_PER_MINUTE = int(os.getenv('AI_RATE_LIMIT_PER_MINUTE', '60'))

# ====================================================================
# FastAPI 应用配置
# ====================================================================
# FastAPI 监听主机地址（0.0.0.0 表示监听所有网卡）
FASTAPI_HOST = os.getenv('APP_HOST', '0.0.0.0')

# FastAPI 监听端口
FASTAPI_PORT = int(os.getenv('APP_PORT', '8990'))

# 应用运行环境（development/staging/production）
APP_ENV = os.getenv('APP_ENV', 'development')

# 是否启用调试模式（⚠️ 生产环境必须设置为 False）
DEBUG = os.getenv('DEBUG', 'true').lower() == 'true'

# ====================================================================
# 安全配置
# ====================================================================
# JWT Secret Key（⚠️ 生产环境必须修改为强随机字符串）
JWT_SECRET_KEY = os.getenv('JWT_SECRET_KEY', 'change-this-to-a-random-secret-key-in-production')

# JWT Token 过期时间（小时）
JWT_EXPIRATION_HOURS = int(os.getenv('JWT_EXPIRATION_HOURS', '24'))

# CORS 允许的源（逗号分隔多个域名，* 表示允许所有）
# ⚠️ 生产环境强烈建议指定具体域名，不要使用 *
CORS_ALLOWED_ORIGINS = os.getenv('CORS_ALLOWED_ORIGINS', '*').split(',')

# API 速率限制（每分钟请求数）
API_RATE_LIMIT = int(os.getenv('API_RATE_LIMIT', '100'))

# ====================================================================
# 日志配置
# ====================================================================
# 日志级别（DEBUG/INFO/WARNING/ERROR/CRITICAL）
LOG_LEVEL = os.getenv('LOG_LEVEL', 'INFO')

# 日志文件路径
LOG_FILE = os.getenv('LOG_FILE_PATH', 'handband_collector.log')

# 日志保留天数
LOG_RETENTION_DAYS = int(os.getenv('LOG_RETENTION_DAYS', '30'))

# ====================================================================
# 业务配置
# ====================================================================
# 批量存储大小
BATCH_SIZE = int(os.getenv('BATCH_SIZE', '100'))

# 最大重试次数
MAX_RETRIES = int(os.getenv('MAX_RETRIES', '3'))

# 重试延迟（秒）
RETRY_DELAY = int(os.getenv('RETRY_DELAY', '1'))

# 时间戳基准值（用于缩小比对时间所需的内存值）
BASE_TIMESTAMP = 1735660800

# 旷工阈值（秒）/ Absenteeism threshold (seconds)
NOT_WORK_MILLION = int(os.getenv('NOT_WORK_MILLION', '7200'))

# 默认查询天数
DEFAULT_QUERY_DAYS = int(os.getenv('DEFAULT_QUERY_DAYS', '30'))

# 时区设置
TIMEZONE = os.getenv('TIMEZONE', 'Asia/Shanghai')

# WebSocket 连接超时（秒）
WEBSOCKET_TIMEOUT = int(os.getenv('WEBSOCKET_TIMEOUT', '300'))

# ====================================================================
# 功能开关
# ====================================================================
# 是否启用分析结果缓存
ENABLE_ANALYSIS_CACHE = os.getenv('ENABLE_ANALYSIS_CACHE', 'true').lower() == 'true'

# 缓存过期时间（秒）
CACHE_EXPIRATION_SECONDS = int(os.getenv('CACHE_EXPIRATION_SECONDS', '3600'))

# 是否启用详细错误信息（仅开发环境建议开启）
ENABLE_DETAILED_ERRORS = os.getenv('ENABLE_DETAILED_ERRORS', 'true').lower() == 'true'

# 是否启用性能监控
ENABLE_PERFORMANCE_MONITORING = os.getenv('ENABLE_PERFORMANCE_MONITORING', 'false').lower() == 'true'

# 是否启用审计日志
ENABLE_AUDIT_LOG = os.getenv('ENABLE_AUDIT_LOG', 'true').lower() == 'true'

# ====================================================================
# IoT 模块配置 / IoT Module Configuration
# ====================================================================
IOT_CONFIG = {
    # 设备监控配置
    "device_monitoring": {
        "offline_threshold_minutes": int(os.getenv('IOT_OFFLINE_THRESHOLD', '10')),  # 设备离线阈值(分钟)
        "heartbeat_timeout_minutes": int(os.getenv('IOT_HEARTBEAT_TIMEOUT', '5')),  # 心跳超时阈值(分钟)
        "health_check_interval": int(os.getenv('IOT_HEALTH_CHECK_INTERVAL', '60')),  # 健康检查间隔(秒)
        "max_concurrent_processing": int(os.getenv('IOT_MAX_CONCURRENT', '50')),  # 最大并发处理数
        "cleanup_threshold_hours": int(os.getenv('IOT_CLEANUP_THRESHOLD', '24')),  # 设备清理阈值(小时)
        "max_devices": int(os.getenv('IOT_MAX_DEVICES', '10000'))  # 最大设备数量
    },

    # 数据处理配置
    "data_processing": {
        "processing_timeout": int(os.getenv('IOT_PROCESSING_TIMEOUT', '30')),  # 数据处理超时(秒)
        "location_timeout": int(os.getenv('IOT_LOCATION_TIMEOUT', '30')),  # 定位处理超时(秒)
        "health_timeout": int(os.getenv('IOT_HEALTH_TIMEOUT', '45')),  # 健康数据处理超时(秒)
        "audio_timeout": int(os.getenv('IOT_AUDIO_TIMEOUT', '60')),  # 音频处理超时(秒)
        "batch_size": int(os.getenv('IOT_BATCH_SIZE', '100')),  # 批处理大小
        "max_batch_size": int(os.getenv('IOT_MAX_BATCH_SIZE', '1000')),  # 最大批处理大小
        "db_operation_timeout": int(os.getenv('IOT_DB_TIMEOUT', '10')),  # 数据库操作超时(秒)
        "enable_preprocessing": os.getenv('IOT_ENABLE_PREPROCESSING', 'true').lower() == 'true'  # 启用预处理
    },

    # 命令处理配置
    "command_handling": {
        "default_timeout": int(os.getenv('IOT_COMMAND_TIMEOUT', '30')),  # 默认命令超时(秒)
        "max_queue_size": int(os.getenv('IOT_MAX_QUEUE_SIZE', '5000')),  # 最大队列大小
        "max_history_size": int(os.getenv('IOT_MAX_HISTORY', '1000')),  # 最大历史记录数
        "batch_command_concurrency": int(os.getenv('IOT_BATCH_CONCURRENCY', '50')),  # 批量命令并发数
        "single_device_concurrency": int(os.getenv('IOT_SINGLE_CONCURRENCY', '10')),  # 单设备命令并发数
        "enable_retry": os.getenv('IOT_ENABLE_RETRY', 'true').lower() == 'true'  # 启用重试
    },

    # 错误处理配置
    "error_handling": {
        "max_retries": int(os.getenv('IOT_MAX_RETRIES', '3')),  # 最大重试次数
        "retry_delay": float(os.getenv('IOT_RETRY_DELAY', '1.0')),  # 重试延迟(秒)
        "circuit_breaker_threshold": int(os.getenv('IOT_CIRCUIT_THRESHOLD', '5')),  # 断路器阈值
        "circuit_breaker_timeout": int(os.getenv('IOT_CIRCUIT_TIMEOUT', '60'))  # 断路器超时(秒)
    },

    # 数据验证配置
    "validation": {
        "strict_validation": os.getenv('IOT_STRICT_VALIDATION', 'false').lower() == 'true',  # 严格验证模式
        "data_confidence_threshold": float(os.getenv('IOT_CONFIDENCE_THRESHOLD', '0.7')),  # 数据置信度阈值
        "required_fields_check": os.getenv('IOT_REQUIRED_FIELDS_CHECK', 'true').lower() == 'true'  # 必填字段检查
    },

    # 日志配置
    "logging": {
        "iot_log_level": os.getenv('IOT_LOG_LEVEL', 'INFO'),  # IoT模块日志级别
        "device_log_retention_days": int(os.getenv('IOT_LOG_RETENTION', '30')),  # 设备日志保留天数
        "memory_limit_mb": int(os.getenv('IOT_MEMORY_LIMIT', '512')),  # 内存使用限制(MB)
        "enable_metrics": os.getenv('IOT_ENABLE_METRICS', 'true').lower() == 'true'  # 启用性能指标
    }
}

# ====================================================================
# 应用功能配置
# ====================================================================
CONFIG = {
    # 邮件配置
    "email": {
        "smtp_server": os.getenv('SMTP_HOST', 'smtp.qq.com'),  # SMTP 服务器地址
        "smtp_port": int(os.getenv('SMTP_PORT', '465')),  # SMTP 服务器端口
        "sender_email": os.getenv('SENDER_EMAIL', '65900370@qq.com'),  # 发件人邮箱
        "sender_password": os.getenv('SMTP_PASSWORD'),  # 发件人密码（必须通过环境变量设置）
        "use_ssl": os.getenv('USE_SSL', 'true').lower() == 'true'  # 是否使用 SSL
    },

    # PDF 报告配置
    "pdf": {
        "wkhtmltopdf_path": os.getenv('WKHTMLTOPDF_PATH', r"E:\\wkhtmltopdf\bin\wkhtmltopdf.exe"),  # wkhtmltopdf 可执行文件路径
        "temp_dir": os.getenv('PDF_TEMP_PATH', tempfile.gettempdir()),  # PDF 临时文件目录
        "storage_path": os.getenv('PDF_STORAGE_PATH', './reports/pdf'),  # PDF 存储路径
        "generation_timeout": int(os.getenv('PDF_GENERATION_TIMEOUT', '60'))  # PDF 生成超时（秒）
    },

    # 日志配置
    "logging": {
        "log_file": os.getenv('LOG_FILE', 'report_generator.log'),  # 日志文件名
        "level": os.getenv('LOG_LEVEL', 'INFO')  # 日志级别
    },

    # 企业微信配置
    "wework": {
        "corpid": os.getenv('WEWORK_CORPID', 'wweaca6b8ea4efb2d1'),  # 企业微信 CorpID
        "corpsecret": os.getenv('WEWORK_CORPSECRET'),  # 企业微信应用 Secret（必须通过环境变量设置）
        "agentid": os.getenv('WEWORK_AGENTID')  # 企业微信应用 AgentID（必须通过环境变量设置）
    }
}


# ====================================================================
# 配置验证函数
# ====================================================================
def validate_config():
    """
    验证配置项是否完整和合法

    在应用启动时调用此函数，确保所有必需的配置项都已正确设置
    """
    errors = []
    warnings = []

    # 检查 AI API 密钥（可选配置，只在使用时才必需）
    # 注意：不同的功能可能使用不同的AI服务，所以这里只给出警告
    if not LAOZHANG_API_KEY:
        warnings.append("未配置 LAOZHANG_API_KEY，如果使用LaoZhang API会失败")

    if not DEEPSEEK_API_KEY:
        warnings.append("未配置 DEEPSEEK_API_KEY，如果使用DeepSeek API会失败")

    if not OPENAI_API_KEY:
        warnings.append("未配置 OPENAI_API_KEY，如果使用OpenAI API会失败")

    # 如果所有AI密钥都未配置，则视为错误（至少需要一个）
    if not any([LAOZHANG_API_KEY, DEEPSEEK_API_KEY, OPENAI_API_KEY]):
        errors.append("⚠️  至少需要配置一个AI API密钥 (LAOZHANG_API_KEY/DEEPSEEK_API_KEY/OPENAI_API_KEY)")

    # 验证生产环境的安全配置
    if APP_ENV == 'production':
        if JWT_SECRET_KEY == 'change-this-to-a-random-secret-key-in-production':
            errors.append("⚠️  生产环境必须修改 JWT_SECRET_KEY")

        if '*' in CORS_ALLOWED_ORIGINS:
            errors.append("⚠️  生产环境不建议使用 CORS_ALLOWED_ORIGINS=*，请指定具体域名")

        if DEBUG:
            errors.append("⚠️  生产环境必须关闭 DEBUG 模式")

    # 打印警告信息
    if warnings:
        print("\n" + "="*70)
        print("⚠️  配置提示：")
        print("="*70)
        for warning in warnings:
            print(f"  💡 {warning}")
        print("="*70 + "\n")

    # 打印错误信息
    if errors:
        print("\n" + "="*70)
        print("❌ 配置验证失败，发现以下问题：")
        print("="*70)
        for error in errors:
            print(f"  ❌ {error}")
        print("="*70)
        print("请在 .env 文件中配置缺失的环境变量，参考 .env.example")
        print("="*70 + "\n")

        # 生产环境下如果配置有误，直接退出
        if APP_ENV == 'production':
            sys.exit(1)
    else:
        print("✅ 配置验证通过")


# ====================================================================
# 配置信息打印（调试用）
# ====================================================================
def print_config_summary():
    """
    打印配置摘要（用于调试，不显示敏感信息）
    """
    print("\n" + "="*70)
    print("📋 当前配置摘要")
    print("="*70)
    print(f"环境: {APP_ENV}")
    print(f"调试模式: {DEBUG}")
    print(f"监听地址: {FASTAPI_HOST}:{FASTAPI_PORT}")
    print(f"日志级别: {LOG_LEVEL}")
    print(f"时区: {TIMEZONE}")
    print(f"Elasticsearch: {len(ELASTICSEARCH_HOSTS)} 个节点")
    print(f"Redis: {REDIS_HOST}:{REDIS_PORT}")
    print(f"MongoDB: 已配置")
    print(f"AI API: LaoZhang={'✅' if LAOZHANG_API_KEY else '❌'}, "
          f"DeepSeek={'✅' if DEEPSEEK_API_KEY else '❌'}, "
          f"OpenAI={'✅' if OPENAI_API_KEY else '❌'}")
    print(f"功能开关: 缓存={'✅' if ENABLE_ANALYSIS_CACHE else '❌'}, "
          f"监控={'✅' if ENABLE_PERFORMANCE_MONITORING else '❌'}, "
          f"审计={'✅' if ENABLE_AUDIT_LOG else '❌'}")
    print("="*70 + "\n")


# ====================================================================
# 在模块加载时进行配置验证（可选）
# ====================================================================
# 如果需要在导入时立即验证配置，取消下面的注释：
# validate_config()
